//TODO:Decide when data is not ready anymore
#include <buola/gui.h>

#include <buola/algorithm/trim.h>

#include <buola/app/ceventloop.h>
#include <buola/gui/cclipboard.h>
#include <buola/gui/cclipboardsource.h>

namespace buola { namespace gui {

CClipboard::CClipboard(int pType)
{
    mType=pType;
    mDataReady=false;
    mDataFailed=false;
    mSource=nullptr;
}

CClipboard::~CClipboard()
{
}

void CClipboard::SetString(const std::wstring &pContents)
{
    if(!OwnSelection()) return;

    InitTargets(); //It automatically adds all text types

    mContentsType=TYPE_STRING;
    mTextContents=pContents;
    mSource=nullptr;
}

void CClipboard::SetURI(const io::CURI &pURI)
{
    if(!OwnSelection()) return;

    InitTargets();
    AddTarget(L"text/uri-list");

    mContentsType=TYPE_URI;
    mTextContents=pURI.ToWString();
    mURIContents=pURI;
    mSource=nullptr;
}

void CClipboard::Clear()
{
    ReleaseSelection();
}

void CClipboard::RequestString(CClipboardTarget *pTarget)
{
    AskForSelection(TYPE_STRING);

    mDataReady=false;
    mDataFailed=false;
    mTarget=pTarget;
}

bool CClipboard::GetString(std::wstring &pContents)
{
    if(!mDataReady&&!mDataFailed)
    {
        RequestString(nullptr);
        mStopLoop=false;
        get_main_event_loop().LoopUntil(mStopLoop);
    }

    if(mDataReady)
    {
        pContents=mReceivedContents;
        mDataReady=false;
        return true;
    }
    else
    {
        pContents.clear();
        mDataFailed=false;
        return false;
    }
}

void CClipboard::RequestURI(CClipboardTarget *pTarget)
{
    AskForSelection(TYPE_URI);

    mDataReady=false;
    mDataFailed=false;
    mTarget=pTarget;
}

bool CClipboard::GetURI(io::CURI &pContents)
{
    if(!mDataReady&&!mDataFailed)
    {
        RequestURI(nullptr);
        mStopLoop=false;
        get_main_event_loop().LoopUntil(mStopLoop);
    }

    if(mDataReady)
    {
        trim_right(mReceivedContents);
        pContents=io::uri(mReceivedContents);
        mDataReady=false;
        return true;
    }
    else
    {
        pContents=io::CURI();
        mDataFailed=false;
        return false;
    }
}

bool CClipboard::ProvideData(const std::wstring &pURL)
{
    if(mContentsType==TYPE_URI)
    {
        if(pURL==L"text/uri-list")
        {
            ServeText(mURIContents.ToWString());
            return true;
        }
    }
    return false;
}

void CClipboard::SelectionReady(const std::wstring &pContents)
{
    mReceivedContents=pContents;
    mStopLoop=true;
    mDataReady=true;
}

void CClipboard::SelectionFailed()
{
    mStopLoop=true;
    mDataFailed=true;
}

void CClipboard::SelectionLost()
{
    if(mSource)
    {
        mSource->OnClipboardLost();
        mSource=nullptr;
    }
}

/*namespace gui*/ } /*namespace buola*/ }
